package com.smrtcold.dev.task;

import com.alibaba.fastjson.JSONObject;
import com.smrtcold.dev.dto.dev.base.Point;
import com.smrtcold.dev.dto.dev.base.XMZDevInfo;
import com.smrtcold.dev.dto.dev.task.CompGroup;
import com.smrtcold.dev.dto.dev.task.CompPoint;
import com.smrtcold.dev.dto.dev.task.DevTask;
import com.smrtcold.dev.init.SystemInit;
import com.smrtcold.dev.utils.Utils;
import lombok.extern.log4j.Log4j2;
import org.mvel2.MVEL;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 智能机机组调参
 */
@Log4j2
@Service
public class SetCompJob extends BaseJob implements Job {


    //缓存的温度-压力对照表
    private static HashMap<String, Float> ylcache = new HashMap<>();
    //数据缓存
    private static HashMap<String, Number> datacache = new HashMap<>();
    // 风扇运行历史记录
    private static HashMap<String, List<Integer>> runFanCache = new HashMap<>();
    //上次控制时间--
    private static HashMap<String, LocalDateTime> localDateTimeHashMap = new HashMap<>();


    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        DevTask task = (DevTask) context.getJobDetail().getJobDataMap().get("TASK");
        //调用父级任务
        super.mainRun(task);
    }

    public void clearCache() {
        ylcache.clear();
        datacache.clear();
        runFanCache.clear();
        localDateTimeHashMap.clear();
    }

    /**
     * 执行任务
     *
     * @param
     * @throws Exception
     */
    @Override
    public boolean run(DevTask task) throws Exception {
        String parameters = task.getParameters();
        List<CompGroup> pointGroups = JSONObject.parseArray(parameters, CompGroup.class);
        int successCount = 0, i = 1;
        for (CompGroup pointGroup : pointGroups) {
            logContert.append(String.format("第%s组：%s\n", i, pointGroup.getName()));
            if (this.setParameters(pointGroup)) {
                successCount++;
            }
            logContert.append("\n");
            i++;
        }
        return successCount == pointGroups.size();
    }

    /**
     * 获取库温设定参数
     *
     * @param pointGroup
     * @throws Exception
     */
    public boolean setParameters(CompGroup pointGroup) throws Exception {
        //1.获取默认参数配置
        //初始化配置参数--这里为了安全，每一个组一个任务参数
        HashMap<String, Object> taskParams = this.initParams(pointGroup.getExtParams());
        //2.判断是否能控制
        // int controlInterval = Integer.parseInt(taskParams.get("控制间隔").toString());//控制间隔
        //1.判断控制周期

        boolean isok = false;
        int model = (Integer) taskParams.get("计算模型");
        switch (model) {
            case 0:
                //标准-智能控制低压--稳压--参数：
                isok = this.mode0(pointGroup, taskParams);
                break;
            case 1:
                //标准--能级100%控制
                isok = this.mode1(pointGroup, taskParams);
                break;
            case 11:
                //--长沙云冷---个性定制多库同启同停
                isok = this.mode11(pointGroup, taskParams);
                break;


            default:

                break;
        }
        return isok;
    }

    /**
     * 算法0：根据最低温度参照表设定目标压力
     * 1.根据最低温度找数据库对应表计算目标压力
     * ---参数：设定温度偏差、制冷剂
     * 2. 判断是否有停风机且不是化霜导致的----
     *
     * @param pointGroup
     * @param extParams
     * @return
     */
    private boolean mode0(CompGroup pointGroup, HashMap<String, Object> extParams) {
        try {
            List<Float> temps = this.getTemps(pointGroup, extParams);

            //判断是否有停机的风机
            int hasstopfan = datacache.getOrDefault("hasstopfan", 0).intValue();
            int status = this.getInt(extParams, "校验压缩机状态"), comprun = 0;
            if (1 == status && null != pointGroup.getComp()) {
                Point point = pointGroup.getComp();
                XMZDevInfo xmzDevInfo = SystemInit.get(point.getDevid());
                String[] split = point.getAddres().split(",");
                List<Integer> vb = xmzDevInfo.batch("VB", split);
                comprun = vb.stream().mapToInt(Integer::intValue).sum();
            }
            //说明当前压缩机组下所有冷间没有运行的
            float sdv = this.getFloat(extParams, "设定压力");//旧的设定值
            float setMaxPress = Float.parseFloat(extParams.get("目标压力上限").toString());
            if (temps.size() == 0) {
                datacache.put("l_pressure", 0);//设定锁
                //风机停止，机组运行
                float stv = this.getFloat(extParams, "停机设定压力", 1.0f);
                return this.write(pointGroup, stv, sdv, extParams);
            } else {
                int setcomp = this.getInt(extParams, "机组运行数量", 3);//new
                log("机组运行：%s,设定：%s, 是否减载：%s  ", comprun, setcomp, hasstopfan);
                if (1 == hasstopfan) {
                    if (comprun >= setcomp) {
                        datacache.put("l_pressure", 1);//设定锁
                        this.log(" 锁定压力为%s", setMaxPress);
                        return this.write(pointGroup, setMaxPress, sdv, extParams);
                    } else if (comprun <= 1) {//
                        datacache.put("l_pressure", 0);//设定锁
                        datacache.put("hasstopfan", 0);
                        //如果存在超温设定--说明需要动态调整设定偏差
                        log(" 解锁");
                        float lowPressure = getLowPressure(extParams, temps);
                        return this.setLowPressure(pointGroup, extParams, 0, temps.get(0), lowPressure, comprun);
                    } else if (0 == comprun) {
                        //防止异常
                        datacache.put("hasstopfan", 0);
                    } else {
                        log(" 等待减载");
                    }
                } else {
                    datacache.put("l_pressure", 0);//设定锁
                    //如果存在超温设定--说明需要动态调整设定偏差
                    float lowPressure = getLowPressure(extParams, temps);
                    return this.setLowPressure(pointGroup, extParams, 0, temps.get(0), lowPressure, comprun);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logContert.append(e.getMessage());
        }
        return false;
    }


    /**
     * 算法1：满能级
     * 1.获取冷间最高运行温度
     * 2.根据自定义设置参数设置压力
     *
     * @param pointGroup
     * @param extParams
     * @return
     */
    private boolean mode1(CompGroup pointGroup, HashMap<String, Object> extParams, int... runColdes) {
        try {
            //1.获取冷库运行数量
            int runColde = 0;
            if (runColdes.length > 0) {
                runColde = runColdes[0];
            } else {
                runColde = this.getRunColde(pointGroup, extParams);
            }
            float sdv = this.getFloat(extParams, "设定压力");
            float lowpressure = this.getFloat(extParams, "目标压力下限", 0.6f);
            float highpressure = this.getFloat(extParams, "目标压力上限", 1.9f);
            int controlInterval = 2;
            float tagPressure = 0.85f;
            float czv = this.getFloat(extParams, "参照压力");//实际压力
            this.log("实际压力：%s", czv);

            Point point = pointGroup.getComp();
            //或者设定的机组运行数量
            int tagrun = getInt(extParams, "冷库_压机_" + runColde);
            XMZDevInfo xmzDevInfo = SystemInit.get(point.getDevid());
            String[] split = point.getAddres().split(",");
            List<Integer> vb = xmzDevInfo.batch("VB", split);
            int size = vb.size(), middle = size / 2;
            int runcount = vb.subList(0, middle).stream().mapToInt(Integer::intValue).sum();
            int fullcount = vb.subList(middle, size).stream().mapToInt(Integer::intValue).sum();
            this.log("冷库运行：%s 目标压机数:%s, 运行机组数：%s, 满能级数：%s \r\n", runColde, tagrun, runcount, fullcount);
            if (0 == runColde) {
                //将压缩机目标压力设置到 下限 默认0.6
                if (runcount == 0) {
                    tagPressure = this.getFloat(extParams, "停机压力设定", 0.85f);
                    controlInterval = this.getInt(extParams, "慢控周期");
                    this.log("冷间、机组未运行：调整下限->%s \r\n", tagPressure);
                } else {
                    tagPressure = highpressure;
                    this.log("冷间停、机组运行：调整上限->%s \r\n", tagPressure);
                }
            } else {
                //低压跟随---todo 这里如果出现问题--可以固定到---0.9？
                if (runcount == tagrun && tagrun == fullcount) {
                    tagPressure = czv;
                    this.log("低压自动跟随->%s \r\n", czv);
                    controlInterval = this.getInt(extParams, "快控周期");
                } else {
                    //1.增加机组，调高能级(运行数量或者能级没达到目标值)
                    if (runcount < tagrun || fullcount < tagrun) {
                        tagPressure = lowpressure;
                        controlInterval = this.getInt(extParams, "快控周期");
                        this.log((runcount < tagrun ? "机组未达到目标数量" : "能级未达到目标值") + "->压力调至下限：%s \r\n", tagPressure);
                    } else {
                        //2.减少机组，稳住能级
                        float yc = this.getFloat(extParams, "延迟停机浮动压力", 1.2f);
                        if (czv > yc) {
                            this.log("延迟减载--->%s \r\n", czv);
                            tagPressure = yc;
                        } else {
                            tagPressure = highpressure;
                            this.log("需减少机组->压力调至上限：%s \r\n", tagPressure);
                        }
                    }
                }
            }
            LocalDateTime lastctlTime = localDateTimeHashMap.get(pointGroup.getDevid() + pointGroup.getName());
            boolean islocak = null != lastctlTime && Duration.between(lastctlTime, LocalDateTime.now()).getSeconds() < controlInterval;
            if (islocak) {
                this.log("控制时间内跳过：%s \n", pointGroup.getName());
                return true;
            }
            return this.write(pointGroup, tagPressure, sdv, extParams);
        } catch (Exception e) {
            e.printStackTrace();
            this.logContert.append(e.getMessage());
        }
        return false;
    }


    /**
     * 算法11：
     * 长沙云冷算法定制--修改中
     * 新增功能：检测风机运行趋势，实现两个冷库同关同停
     *
     * @param pointGroup
     * @param extParams
     * @return
     */
    private boolean mode11(CompGroup pointGroup, HashMap<String, Object> extParams) {

        try {
            int runColde = this.getRunColde(pointGroup, extParams);
            // 检测风机运行趋势，实现同关同停逻辑
            this.detectFanTrendAndSyncControl(pointGroup, extParams, runColde);
            //---设置压力---控制机组
            return this.mode1(pointGroup, extParams, runColde);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
        }

    }

    /**
     * 同启同停--逻辑
     *
     * @param pointGroup
     * @param extParams
     * @return
     */
    private int detectFanTrendAndSyncControl(CompGroup pointGroup, HashMap<String, Object> extParams, int runColde) throws Exception {
        //1.获取冷库运行数量---参与总数---->
        List<CompPoint> points = pointGroup.getPoints();
        int coldcoun = this.getInt(extParams, "冷间同时制冷数", 2);
       int  runmapping=  this.getInt(extParams, "冷间关联运行", 0);
        // 如果冷间数据和运行数一致，则不处理，否则调整冷间数量
        if (runColde == 0) return runColde;
        if (runColde == coldcoun||0==runmapping) {
            //              if(colda.isFw()&&!coldb.isFw()) {
//                  this.logContert.append(" a,b 运行，a 接近停机温度，调整A 浮动温度 ");
//                  this.setTemp(true, colda, extParams);
//              }if(coldb.isFw()&&!colda.isFw()) {
//                this.logContert.append(" a,b 运行，b 接近停机温度，调整b 浮动温度 ");
//                this.setTemp(true, coldb, extParams);
//              }
//              this.restTemp(extParams, points);
            return runColde;
        }



        CompPoint colda = null, coldb = null;  //东、西冷冻
        if (runColde != coldcoun && points.size() >= coldcoun) {
            //这里为了快速迭代，写写死掉
            colda = points.get(0);  // 东冷冻
            coldb = points.get(1);  // 西冷冻
        }
        if (colda == null || coldb == null) {
            this.log("未找到同时启停冷库");
            return runColde;
        }
        boolean isComA = isStopTemp(colda, extParams), isComB = isStopTemp(coldb, extParams);
        int status1 = colda.getStatus(), status2 = coldb.getStatus();
        this.log(" 温度控制开始...run: %s,setrun: %s   \r\n", runColde, coldcoun);
        // } else {
        //0 待机   1：运行制冷  2:停机中
        if (1 == status1) {
            if (datacache.containsKey(colda.getName() + "-temp-ctl")) {
                this.resetTemp(colda, extParams);
                return runColde;
            }
            //a 在运行，已经到范围内
            this.log("a -->制冷中,b-->%s a.sif:%s,b.cs:%s", status2,colda.isFw(),coldb.isCanStart());
            if (0 == status2) {
                if (colda.isFw()) {
//                     todo  a 在运行，已经到范围内-> 强制 a 停机
                    this.logContert.append("  a 运行，温差:T-> 强制 a 停机 \r\n");
                    this.delyeSet(extParams, colda);
                } else if (coldb.isCanStart()) {
                    //a 在运行，未到浮动范围内 --->  强制 B 开启
                    this.logContert.append("a 运行，温差:F--->B:可以启动 \r\n");
                    this.setTemp(true, coldb, extParams);
                }

            }

        } else {
            //a 停机中，---> b 开启
            this.log("a 停机中 b--> %s b.fw:%s,a.cs:%s \r\n", status2, coldb.isFw(), colda.isCanStart());
            if (1 == status2) {
                // if (datacache.containsKey(point.getName() + "-temp-ctl")) {
                if (datacache.containsKey(coldb.getName() + "-temp-ctl")) {
                    this.resetTemp(coldb, extParams);
                    return runColde;
                }
                if (coldb.isFw()) {
                    //b 在运行，已经到浮动范围内---> 强制 b 停机---需要延迟
                    this.logContert.append("b：运行，温差:T---> 强制 b 停机---需要延迟 \r\n");
                    this.delyeSet(extParams, coldb);
                } else if (colda.isCanStart()) {
                    //b 在运行，未到范围内---> 强制 a 开启
                    this.logContert.append("b 运行，温差：F---> a 可以启动 \r\n");
                    this.setTemp(true, colda, extParams);
                }
            }
        }
        return runColde;

    }

    private void delyeSet(HashMap<String, Object> extParams, CompPoint point) throws Exception {
        String key = point.getName() + "-delay";
        LocalDateTime lastctlTime = localDateTimeHashMap.get(key);
        if (null != lastctlTime) {
            int jg = this.getInt(extParams, "强制停机缓冲时间-M", 5);
            if (Duration.between(lastctlTime, LocalDateTime.now()).getSeconds() > jg * 60) {
                this.setTemp(false, point, extParams);
                localDateTimeHashMap.remove(key);
            } else {
                this.log("%s 延迟温度停机--缓冲中...", point.getName());
            }
        } else {
            localDateTimeHashMap.put(key, LocalDateTime.now());
            this.log("%s 开始延迟停机温度", point.getName());
        }
    }

    /**
     * 根据设定温度判断温度是否达到
     *
     * @param
     * @return
     */
    private boolean isStopTemp(CompPoint point, HashMap<String, Object> extParams) {
        double value = point.getTemp().getValue().doubleValue();//获取点位当前温度
        //获取设定
        double st = this.getDouble(extParams, point.getName() + "-白天");
        double fd = this.getDouble(extParams, point.getName() + "-浮动");
        double stv = this.getDouble(extParams, "停止制冷偏差", 0.3);
        point.setFw(Math.abs(value - (st - fd)) <= stv);
        double qqtemp = this.getDouble(extParams, point.getName() + "-强启温度");//获取
        point.setCanStart(value > qqtemp);
        // log(" %s: value:%s st:%s,fd:%s,stv:%s,fw:-> %s ，%s--- \r\n", point.getName(), value,st, fd, stv,point.isFw(),value - Math.abs(st - fd) <= stv);
        //判断当前温度小于等于设定温度（温度是否达到了）
        return value <= (st - fd);
    }


    /**
     *
     * @param isRun:    true ,强制制冷
     * @param point     ：点位
     * @param extParams ：设置参数
     */
    private void setTemp(boolean isRun, CompPoint point, HashMap<String, Object> extParams) throws Exception {
        float stv = this.getFloat(extParams, (isRun ? point.getName() + "-启动偏差" : "-停止偏差"), 0.3f);
        float value = this.getFloat(extParams, point.getName() + "-浮动");
//        if (stv > value) {
//            this.log("，跳过\r\n");
//            return;
//        }
        //float newValue = isRun ?  stv :  stv;
        String devid = this.getAddres(extParams, point.getName() + "-浮动-devid");
        String addres = this.getAddres(extParams, point.getName() + "-浮动-addres");
        boolean isctl = this.isRun(extParams);
        if (null == devid || addres == null) {
            this.log("浮动控制失败！devid 或addres 为空");
            return;
        }
        this.log(" %s,--> %s 强制 %s： 浮动值：%s-> %s, \r\n", isctl ? "控制" : "测试", point.getName(), isRun ? "制冷" : "停机", value, stv);
        if (isctl) {
            datacache.put(point.getName() + "-temp-ctl", 1);
            localDateTimeHashMap.put(point.getName() + "-temp-ctl", LocalDateTime.now());
            this.write(devid, addres, point.getName() + "-浮动", stv, value, null, null);
        }


    }

    /**
     * 设置低压
     *
     * @param pointGroup
     * @param extParams
     * @param temp
     * @param lowPressure
     * @return
     * @throws Exception
     */
    private boolean setLowPressure(CompGroup pointGroup, HashMap<String, Object> extParams, int mode, float temp, float lowPressure, int comprun) throws Exception {
        float tagPressure = lowPressure;
        float czv = this.getFloat(extParams, "参照压力"), sdv = this.getFloat(extParams, "设定压力");
        this.log("设定目标压力：%s,实际压力：%s,最低温度：%s, 计算值：%s,压机状态：%s\r\n", sdv, czv, temp, lowPressure, comprun);
        int controlInterval = 0;//控制频率
        if (comprun > 0) {
            float diff = getFloat(extParams, "浮动偏差");
            float sdediff = getFloat(extParams, "设定压力偏差");
            if (0 != diff && Math.abs(czv - lowPressure) <= diff) {
                log("浮动偏差内,目标设置为实际值:%s \r\n", czv);
                tagPressure = czv;
                controlInterval = this.getInt(extParams, "快控周期");
            } else if (extParams.containsKey("启用偏差纠正") && 1 == this.getInt(extParams, "启用偏差纠正")) {
                sdediff = 0.0f != sdediff ? sdediff : czv - sdv;//如果设定压力偏差!=0，使用设定压力偏差，否则使用计算偏差
                if (czv < (lowPressure - diff)) {
                    tagPressure = sdv + sdediff;
                    log("+%s \r\n", sdediff);
                } else if (czv > (lowPressure + diff)) {
                    tagPressure = sdv - sdediff;
                    log("-%s \r\n", sdediff);
                }
                this.log("偏差纠正1： 上次: %s --> %s ，偏差：%s ，当前：%s --> %s \r\n", czv, sdv, sdediff, lowPressure, tagPressure);
                controlInterval = this.getInt(extParams, "慢控周期");
            } else if (0.0 != sdediff) {
                tagPressure = lowPressure + sdediff;
                this.log("偏差修正2： 目标值：{}，修正值：{} \r\n", lowPressure, tagPressure);
                controlInterval = this.getInt(extParams, "慢控周期");
            }
        } else {
            tagPressure = lowPressure;// 如果风机运行，机组停机，设定目标值等于计算值
            controlInterval = this.getInt(extParams, "慢控周期");
        }
        LocalDateTime lastctlTime = localDateTimeHashMap.get(pointGroup.getDevid() + pointGroup.getName());
        boolean islocak = null != lastctlTime && Duration.between(lastctlTime, LocalDateTime.now()).getSeconds() < controlInterval;
        if (islocak) {
            logContert.setLength(0);
            this.log("控制时间内跳过：%s \n", pointGroup.getName());
            log.info("控制时间内跳过：{}", pointGroup.getName());
            return true;
        }


        this.log("模型:%s,计算值:%s, 设定值：%s \r\n", mode, lowPressure, tagPressure);
        //4.设定压缩机组压力
        return this.write(pointGroup, tagPressure, sdv, extParams);
    }

    private boolean write(CompGroup pointGroup, float tagPressure, float sdv, HashMap<String, Object> extParams) throws Exception {
        boolean isctl = isRun(extParams);
        if (!isctl) {
            this.log("测试模式，跳过控制");
            return false;
        }
        float max = Float.parseFloat(extParams.get("目标压力上限").toString()), min = Float.parseFloat(extParams.get("目标压力下限").toString());
        Point setPoint = pointGroup.getSetPoint();
        try {
            return this.write(setPoint.getDevid(), setPoint.getAddres(), setPoint.getName(), tagPressure, sdv, max, min);
        } finally {
            localDateTimeHashMap.put(pointGroup.getDevid() + pointGroup.getName(), LocalDateTime.now());
        }
    }

    private float getLowPressure(HashMap<String, Object> extParams, List<Float> temps) {
        float tempdiff = this.getFloat(extParams, "设定温度偏差");
        if (extParams.containsKey("超温设定")) {
            float overTempset = this.getFloat(extParams, "超温设定");
            boolean isOverTemp = temps.stream().anyMatch(temp -> temp > overTempset);
            if (isOverTemp) {
                float overtemdiff = this.getFloat(extParams, "超温偏差");
                tempdiff += overtemdiff;
                log("超设定%s温度\r\n", overtemdiff);
            }
        }
        return this.getlowMode0_Pressure(extParams.containsKey("制冷剂") ? extParams.get("制冷剂").toString() : "R507A", temps.get(0) + tempdiff);
    }

    //模型1 ---获取制冷冷间数量
    private int getRunColde(CompGroup pointGroup, HashMap<String, Object> extParams) throws Exception {
        int ispcbw = (Integer) extParams.get("排除变温");
        List<CompPoint> points = pointGroup.getPoints();
        int count = 0,//实际正在制冷的总数（不包含化霜的）
                allcount = points.size(),//总数
                expcount = 0;//参与计算的总数

        for (int m = 0; m < allcount; m++) {
            CompPoint point = points.get(m);
            //判断是否跳过变温
            if (Utils.isnotNull(point.getName()) && point.getName().indexOf("变温") > -1 && 1 == ispcbw) {
                continue;
            }
            expcount++;
            XMZDevInfo xmzDevInfo = SystemInit.get(point.getDevid());
            String addres = point.getFan().getAddres();
            String[] run_def = addres.split("@");//获取制冷或者化霜
            //制冷逻辑判断
            String[] runaddres = run_def[0].split(",");
            List<Integer> run = xmzDevInfo.batch("VB", runaddres);
            int sumrun = run.stream().mapToInt(Integer::intValue).sum();//获取运行风机总数
            String key = pointGroup.getName() + "_" + point.getName() + "_fanrun";
            int oldrun = datacache.getOrDefault(key, 0).intValue();
            //获取冷间温度
            if (null != point.getTemp()) {
                float temp = xmzDevInfo.readAddres(point.getTemp().getAddres()).floatValue();
                point.getTemp().setValue(temp);
            }
            boolean isaddfan = false;
            this.logContert.append(String.format("%s->%s,o:%s,r:%s , ", m, point.getName(),oldrun,sumrun));
            if (sumrun > 0) {
                if (oldrun != sumrun) {
                    //刚开始期待制冷
                    if (oldrun == 0 && sumrun == 1 && datacache.containsKey(point.getName() + "-temp-ctl")) {
                        this.resetTemp(point, extParams);
                    }
                    if (oldrun < sumrun) {
                        isaddfan = true;
                        datacache.put(key + "_add", 1);
                        this.log("3. %s-->%s ,增加", oldrun, sumrun);
                    } else {

                        //风机减少--->判断是否开启化霜逻辑---因为化霜前会停机导致程序误判--所以条件1调整为强制执行
                        if (( (double) sumrun /(double) run.size()) * 100 >= 50) {
                            isaddfan = true;
                            datacache.put(key + "_add", 1);
                        } else {
                            datacache.put(key + "_add", 0);
                        }
                        this.log("2.1 减少 oldrun:%s,sumrun:%s,isaddfan: %s", oldrun, sumrun, isaddfan);

                        //化霜的校验---感觉意义不大
                        //                        if (run_def.length == 2) {
                        //                            List<Integer> orDefault = runFanCache.getOrDefault(key, new ArrayList<>());
                        //                            if (orDefault.size() > 0) {
                        //                                //获取化霜
                        //                                int c = 0;
                        //                                List<Integer> hs = xmzDevInfo.batch("VB", run_def[1].split(","));
                        //                                for (int i = 0; i < run.size(); i++) {
                        //                                    if (run.get(i) != orDefault.get(i) && 1 == hs.get(i)) {
                        //                                        c++;
                        //                                    }
                        //                                }
                        //                                // 判断是否之前风机是否有化霜，
                        //                                if (sumrun + c >= oldrun||(sumrun/run.size())*100>=50) {
                        //                                    isaddfan = datacache.getOrDefault(key + "_add", 0).intValue() == 1;
                        //                                } else {
                        //                                    datacache.put(key + "_add", 0);
                        //                                }
                        //                                this.log("2.1 制冷(%s)+化霜(%s)： --->原来： %s ,结果： %s ", sumrun, c, oldrun, isaddfan);
                        //                            } else {
                        //                                this.log("2.2 %s", sumrun);
                        //                                datacache.put(key + "_add", 0);
                        //                            }
                        //                        } else {
                        //                            isaddfan = false;
                        //                            datacache.put(key + "_add", 0);
                        //                            this.log("3. %s-->%s ,减少", oldrun, sumrun);
                        //                        }
                    }
                     datacache.put(key, sumrun);
                } else {
                    isaddfan = datacache.getOrDefault(key + "_add", 0).intValue() == 1;
                    this.log("4. 不变 run:%s-->%s", sumrun, isaddfan);
                }
                if (isaddfan && sumrun > 0) {
                    count++;
                    point.setStatus(1);
                } else {
                    point.setStatus(2);
                }
            } else {
                this.log("5. 风机未运行");
                datacache.getOrDefault(key + "_add", 0);
                datacache.put(key, 0);
//                runFanCache.put(key, new ArrayList<>());
                point.setStatus(0);
            }
            point.setFanCount(sumrun);
            this.logContert.append("\r\n");
        }
        //todo冷库 全部停止后重设温度
        if (0 == count) {
            this.restTemp(extParams, points);
        }
        return count;
    }

    private void restTemp(HashMap<String, Object> extParams, List<CompPoint> points) throws Exception {
        for (CompPoint point : points) {
            float a = this.getFloat(extParams, point.getName() + "-浮动");
            float b = this.getFloat(extParams, point.getName() + "-浮动-value");
            if (datacache.containsKey(point.getName() + "-temp-ctl") || Math.abs(a - b) > 0.01) {
                this.resetTemp(point, extParams);
            }
            if (localDateTimeHashMap.containsKey(point.getName() + "-delay")) {
                localDateTimeHashMap.remove(point.getName() + "-delay");
            }
        }
    }

    /**
     * 冷库停止后重设温度
     *
     * @param point     :当前冷库点位
     * @param extParams
     * @throws Exception
     */
    private void resetTemp(CompPoint point, HashMap<String, Object> extParams) throws Exception {

        float setValue = this.getFloat(extParams, point.getName() + "-浮动-value");
        float value = this.getFloat(extParams, point.getName() + "-浮动");
        String devid = this.getAddres(extParams, point.getName() + "-浮动-devid");
        String addres = this.getAddres(extParams, point.getName() + "-浮动-addres");
        boolean isctl = this.isRun(extParams);
        if (null == devid || addres == null) {
            this.log("重置浮动控制失败！devid 或addres 为空");
            return;
        }
        this.log(" %s,  重置：%s ： 浮动值：%s-> %s, \r\n", isctl ? "控制" : "测试", point.getName(), value, setValue);
        if (isctl) {
            datacache.remove(point.getName() + "-temp-ctl");
            this.write(devid, addres, point.getName() + "-浮动", setValue, value, null, null);
        }
    }


    /**
     * 获取运行中冷库温度---升序--->方便找到最高温度
     *
     * @param pointGroup
     * @param extParams
     * @return
     * @throws Exception
     */
    private List<Float> getTemps(CompGroup pointGroup, HashMap<String, Object> extParams) throws Exception {
        int ispcbw = (Integer) extParams.get("排除变温");
        List<Float> temps = new ArrayList<>();
        List<CompPoint> points = pointGroup.getPoints();

        for (CompPoint point : points) {
            //判断是否跳过变温
            if (Utils.isnotNull(point.getName()) && point.getName().indexOf("变温") > -1 && 1 == ispcbw) {
                continue;
            }
            XMZDevInfo xmzDevInfo = SystemInit.get(point.getDevid());
            String addres = point.getFan().getAddres();
            String[] run_def = addres.split("@");//获取制冷或者化霜
            //制冷逻辑判断
            String[] runaddres = run_def[0].split(",");
            List<Integer> run = xmzDevInfo.batch("VB", runaddres);
            int sumrun = run.stream()
                    .mapToInt(Integer::intValue)
                    .sum();
            int sunhs = 0;

            String key = pointGroup.getName() + "_" + point.getName() + "_fanrun";
            Number oldrun = datacache.getOrDefault(key, 0);
            if (run_def.length == 2) {
                List<Integer> hs = xmzDevInfo.batch("VB", run_def[1].split(","));
                sunhs = hs.stream()
                        .mapToInt(Integer::intValue)
                        .sum();
                //判断是减载风机
                if (0 == datacache.getOrDefault("hasstopfan", 0).intValue()) {
                    if (sumrun > 0 && sumrun + sunhs != runaddres.length && oldrun.intValue() > sumrun) {
                        if (runFanCache.containsKey(key)) {
                            runFanCache.get(key).add(sumrun);
                        } else {
                            List<Integer> list = new ArrayList<>();
                            list.add(sumrun);
                            runFanCache.put(key, list);
                        }
                    } else if (sumrun > 0 && sumrun > oldrun.intValue()) {
                        if (runFanCache.containsKey(key)) {
                            runFanCache.get(key).clear();
                        } else {
                            runFanCache.put(key, new ArrayList<>());
                        }
                    }
                } else {
                    //runFanCache.put(key, new ArrayList<>());
                }
                if (runFanCache.containsKey(key) && runFanCache.get(key).size() >= 2) {
                    datacache.put("hasstopfan", 1);
                    runFanCache.clear();
                }

            }
            float temp = xmzDevInfo.readAddres(point.getTemp().getAddres()).floatValue();
            if (sumrun > 0) {
                temps.add(temp);
            }
            datacache.put(key, sumrun);
            this.log("冷间：%s，温度：%s, 制冷： 上次：%s ~ 当前：%s个,化霜：%s个，停机：%s ， 是否计算：%s \r\n", point.getFan().getName(), temp, oldrun, sumrun, sunhs, (runaddres.length - sumrun - sunhs), sumrun > 0);
        }
        if (temps.size() > 0) {
            temps.sort(Float::compareTo);//升序排序
        } else {
            //  this.log(logContert, "%s，风机未运行，跳过\n", pointGroup.getName());
        }

        return temps;
    }

    /**
     * 根据制冷剂类型和温度计算目标压力值（模型0版本1）
     *
     * @param refrigerant 制冷剂类型（如"R507A"）
     * @param temp        当前温度值
     * @param extParams   扩展参数Map，包含压力计算相关配置
     * @return 计算得出的目标压力值
     * @throws RuntimeException 当未找到匹配的压力值时抛出异常
     */
    //对比获取
    private float getlowMode0_Pressure1(String refrigerant, double temp, HashMap<String, Object> extParams) {
        String _ckey = refrigerant + "_" + temp;
        Float aDouble = ylcache.get(_ckey);
        if (null != aDouble) return aDouble;
        //
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("temp", Utils.getDouble(temp));
        for (Map.Entry<String, Object> entry : extParams.entrySet()) {
            String key = entry.getKey();
            if (key.contains("$") && key.startsWith("M1")) {
                key = key.replace("$", "temp").replace("M1", "");
                if (MVEL.eval(key, dataMap, Boolean.class)) {
                    float setpressdiff = getFloat(extParams, "设定压力偏差");
                    float value = Float.parseFloat(entry.getValue().toString()) + setpressdiff;
                    ylcache.put(_ckey, value);
                    return value;
                }
            }
        }
        throw new RuntimeException("未找到对应的压力值");
    }


}
